<template>
  <div class="media-grid">
    <div
      v-for="item in mediaFiles"
      :key="item.id"
      class="media-card"
      @click="handleItemClick(item)"
    >
      <!-- 预览区域 -->
      <div class="preview">
        <!-- 图片类型 -->
        <template v-if="item.type === 'image'">
          <el-image
            :src="item.url"
            fit="cover"
            :preview-src-list="[item.url]"
            :initial-index="0"
            :preview-teleported="true"
            @click.stop="handleImagePreview(item)"
          >
            <template #error>
              <div class="error-placeholder">
                <el-icon><Picture /></el-icon>
              </div>
            </template>
          </el-image>
        </template>
        <!-- 文档类型 -->
        <template v-else>
          <div class="file-preview" :class="getFileTypeClass(item)">
            <div class="file-type-content">
              <el-icon><component :is="getDocumentIcon(item)" /></el-icon>
              <span class="ext">{{ getFileExtension(item.name) }}</span>
            </div>
          </div>
        </template>

        <!-- 操作按钮 -->
        <div class="actions">
          <el-button class="action-btn" circle @click.stop="handleCopyLink(item)">
            <el-icon><Link /></el-icon>
          </el-button>
          <el-button class="action-btn" circle @click.stop="handleMoveGroup(item)">
            <el-icon><FolderAdd /></el-icon>
          </el-button>
          <el-button class="action-btn" circle @click.stop="handleDelete(item)">
            <el-icon><Delete /></el-icon>
          </el-button>
        </div>
      </div>

      <!-- 信息区域 -->
      <div class="info">
        <div class="name" :title="item.name">{{ item.name }}</div>
        <div class="meta">
          <span class="size">{{ item.size }}</span>
          <span class="time">{{ formatTime(item.updateTime) }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
/**
 * 媒体网格视图组件
 *
 * 功能：
 * 1. 以网格卡片形式展示媒体文件
 * 2. 支持图片预览和文档文件展示
 * 3. 提供复制链接和删除操作
 */
import { defineProps, defineEmits } from 'vue'
import {
  Picture,
  Document,
  Link,
  Delete,
  FolderAdd,
  Files,
  Headset,
  VideoPlay,
  Terminal,
  Brush,
} from '@element-plus/icons-vue'
import { getFileExtension, getFileTypeClass, formatTime } from '@/utils/mediaUtils'

/**
 * 媒体文件类型定义
 */
interface MediaFile {
  id: number
  name: string
  type: 'image' | 'document'
  url: string
  size: string
  updateTime: string
  groupId: number
  typeDisplay: 'image' | 'document'
}

/**
 * 组件属性
 */
const props = defineProps<{
  /** 要展示的媒体文件列表 */
  mediaFiles: MediaFile[]
}>()

/**
 * 组件事件
 */
const emit = defineEmits<{
  /** 复制链接事件 */
  (e: 'copyLink', item: MediaFile): void
  /** 删除文件事件 */
  (e: 'delete', item: MediaFile): void
  /** 图片预览事件 */
  (e: 'preview', item: MediaFile): void
  /** 项目点击事件 */
  (e: 'itemClick', item: MediaFile): void
  /** 移动分组事件 */
  (e: 'moveGroup', item: MediaFile): void
}>()

/**
 * 处理复制链接事件
 */
const handleCopyLink = (item: MediaFile) => {
  emit('copyLink', item)
}

/**
 * 处理删除事件
 */
const handleDelete = (item: MediaFile) => {
  emit('delete', item)
}

/**
 * 处理图片预览事件
 */
const handleImagePreview = (item: MediaFile) => {
  if (item.type === 'image') {
    emit('preview', item)
  }
}

/**
 * 处理项目点击事件
 */
const handleItemClick = (item: MediaFile) => {
  emit('itemClick', item)
}

/**
 * 处理移动分组事件
 */
const handleMoveGroup = (item: MediaFile) => {
  emit('moveGroup', item)
}

/**
 * 获取文档类型对应的图标
 */
const getDocumentIcon = (item) => {
  const ext = getFileExtension(item.name)

  // 文档类型
  if (['doc', 'docx', 'rtf', 'odt', 'pages'].includes(ext)) return 'Document'

  // PDF类型
  if (['pdf'].includes(ext)) return 'Document'

  // 文本类型
  if (['txt', 'md', 'json', 'log', 'xml', 'html', 'css', 'js', 'ts'].includes(ext))
    return 'Document'

  // Excel类型
  if (['xls', 'xlsx', 'csv', 'numbers', 'ods'].includes(ext)) return 'Document'

  // PowerPoint类型
  if (['ppt', 'pptx', 'key', 'odp'].includes(ext)) return 'Document'

  // 压缩文件类型
  if (['zip', 'rar', '7z', 'tar', 'gz'].includes(ext)) return 'Files'

  // 音频类型
  if (['mp3', 'wav', 'ogg', 'flac', 'm4a', 'aac'].includes(ext)) return 'Headset'

  // 视频类型
  if (['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm'].includes(ext)) return 'VideoPlay'

  // 代码类型
  if (['java', 'py', 'cpp', 'c', 'cs', 'php', 'rb', 'go', 'swift'].includes(ext)) return 'Terminal'

  // 设计文件类型
  if (['psd', 'ai', 'sketch', 'fig', 'xd'].includes(ext)) return 'Brush'

  return 'Document'
}
</script>

<style lang="scss" scoped>
// 导入主题变量和混合器
@use '@/assets/styles/theme/base.scss' as *;
@use '@/assets/styles/mixins.scss' as *;

/**
 * 网格视图样式
 */
.media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
  padding: 16px;

  /**
   * 媒体卡片项
   */
  .media-card {
    border-radius: $radius-medium;
    overflow: hidden;
    background: $bg-base;
    @include transition(all);
    cursor: pointer;
    border: 1px solid $border-light;

    &:hover {
      transform: translateY(-2px);
      border-color: $color-primary;
      @include box-shadow('light');

      .preview {
        .actions {
          opacity: 1;
          transform: translateY(0);
        }
      }
    }

    /**
     * 媒体预览区域
     */
    .preview {
      position: relative;
      width: 100%;
      padding-bottom: 75%;
      background: $bg-light;
      overflow: hidden;

      .el-image {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        @include transition(all);
      }

      .error-placeholder {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        @include flex-center;
        color: $text-secondary;
        font-size: 32px;
      }

      /**
       * 文件类型预览样式
       */
      .file-preview {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;

        .file-type-content {
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 8px;

          .el-icon {
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
          }

          .ext {
            display: inline-block;
            padding: 3px 8px;
            border-radius: $radius-base;
            background: rgba(255, 255, 255, 0.9);
            font-size: $font-size-small;
            font-weight: 500;
            text-transform: lowercase;
            line-height: 1;
          }
        }

        &.file-type-doc {
          @include gradient-bg(#4285f4, #70a3f7);
          .ext {
            color: #4285f4;
          }
        }

        &.file-type-docx {
          @include gradient-bg(#4285f4, #70a3f7);
          .ext {
            color: #4285f4;
          }
        }

        &.file-type-pdf {
          @include gradient-bg(#ff5252, #ff8585);
          .ext {
            color: #ff5252;
          }
        }

        &.file-type-txt {
          @include gradient-bg(#34a853, #68c883);
          .ext {
            color: #34a853;
          }
        }

        &.file-type-json {
          @include gradient-bg(#4caf50, #81c784);
          .ext {
            color: #4caf50;
          }
        }

        &.file-type-xls,
        &.file-type-xlsx {
          @include gradient-bg(#0f9d58, #63d08f);
          .ext {
            color: #0f9d58;
          }
        }

        &.file-type-ppt,
        &.file-type-pptx {
          @include gradient-bg(#db4437, #f8866d);
          .ext {
            color: #db4437;
          }
        }

        &.file-type-zip {
          @include gradient-bg(#795548, #a67c52);
          .ext {
            color: #795548;
          }
        }

        &.file-type-audio {
          @include gradient-bg(#9c27b0, #ce93d8);
          .ext {
            color: #9c27b0;
          }
        }

        &.file-type-video {
          @include gradient-bg(#ff9800, #ffcc80);
          .ext {
            color: #ff9800;
          }
        }

        &.file-type-code {
          @include gradient-bg(#3f51b5, #7986cb);
          .ext {
            color: #3f51b5;
          }
        }

        &.file-type-design {
          @include gradient-bg(#e91e63, #f48fb1);
          .ext {
            color: #e91e63;
          }
        }

        &.file-type-other {
          @include gradient-bg(#607d8b, #90a4ae);
          .ext {
            color: #607d8b;
          }
        }

        &.file-type-image {
          @include gradient-bg(#00bcd4, #80deea);
          .ext {
            color: #00bcd4;
          }
        }
      }

      /**
       * 操作按钮
       */
      .actions {
        position: absolute;
        top: 8px;
        right: 8px;
        display: flex;
        gap: 4px;
        opacity: 0;
        transform: translateY(-10px);
        @include transition(all);

        .action-btn {
          width: 32px;
          height: 32px;
          background: rgba(255, 255, 255, 0.9);
          backdrop-filter: blur(4px);
          border: none;
          color: $text-regular;

          &:hover {
            background: white;
            transform: translateY(-2px);
            color: $color-primary;

            &:last-child {
              color: $color-danger;
            }
          }
        }
      }
    }

    /**
     * 媒体信息区域
     */
    .info {
      padding: 12px;

      .name {
        font-size: $font-size-small;
        font-weight: 500;
        color: $text-primary;
        margin-bottom: 6px;
        @include text-ellipsis;
      }

      .meta {
        display: flex;
        justify-content: space-between;
        font-size: $font-size-small;

        .size {
          color: $text-regular;
          background: $bg-light;
          padding: 1px 6px;
          border-radius: $radius-base;
        }

        .time {
          color: $text-secondary;
        }
      }
    }
  }
}
</style>
